package com.hall.items.msg;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.hall.TripletProcessResult;
import com.hall.items.aggr.*;
import com.hall.items.repo.MyViewCachedUpdater;
import com.hall.items.service.ItemsService;
import com.hall.weaponenhancement.aggr.GoldAccount;
import com.hall.weaponenhancement.service.GoldService;
import com.mbrs.aggr.MyUserBan;
import com.mbrs.service.LoginOrRegisterResult;
import com.mbrs.service.PairProcessResult;
import dml.accounting.aggr.TransferResult;
import dml.game.weapon.proc.MultiPackEquipWeaponResult;
import dml.game.weapon.proc.UnloadWeaponResult;
import dml.operation.sto.aggr.Command;
import erp.process.definition.json.ProcessJsonUtil;
import erp.process.definition.json.TypedResultJson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Component
public class MsgReceiver {

    @Autowired
    private ItemsService itemsService;

    @Autowired
    private GoldService goldService;

    @Autowired
    private MsgSender msgSender;

    @Autowired
    private MyViewCachedUpdater myViewCachedUpdater;

    private Gson gson = new Gson();

    private Executor tp = Executors.newCachedThreadPool();

    @KafkaListener(id = "hall", topics = "process")
    public void listen(String in) {
        String processName = ProcessJsonUtil.getProcessName(in);
        TypedResultJson typedResultJson = ProcessJsonUtil.getProcessResult(in);
        if ("com.mbrs.service.LoginService.loginOrRegister".equals(processName)) {
            Type type = new TypeToken<PairProcessResult<MyUserBan, LoginOrRegisterResult>>() {
            }.getType();
            PairProcessResult<MyUserBan, LoginOrRegisterResult> rslt = gson.fromJson(typedResultJson.getResultJson(),
                    type);
            itemsService.createFirstPlayerWeaponPack(rslt);
            msgSender.sendProcess(false);

            goldService.initGoldAccountsForNewPlayer(rslt);
            msgSender.sendProcess(false);
        } else if ("com.sto.service.SceneTriggeredOperationService.sendCmd".equals(processName)) {
            Command command = gson.fromJson(typedResultJson.getResultJson(), Command.class);
            itemsService.createWeaponAndEquip(command);
            msgSender.sendProcess(false);
        } else if ("com.hall.items.service.ItemsService.equipWeapon".equals(processName)) {
            tp.execute(() -> {
                Type type = new TypeToken<MultiPackEquipWeaponResult<MyWeapon, MyPlayerWeaponPack>>() {
                }.getType();
                MultiPackEquipWeaponResult<MyWeapon, MyPlayerWeaponPack> rslt = gson.fromJson(typedResultJson.getResultJson(),
                        type);
                itemsService.updatePackCombatValueByEquipWeapon(rslt);
                msgSender.sendProcess(false);
            });
            tp.execute(() -> {
                Type type = new TypeToken<MultiPackEquipWeaponResult<MyWeapon, MyPlayerWeaponPack>>() {
                }.getType();
                MultiPackEquipWeaponResult<MyWeapon, MyPlayerWeaponPack> rslt = gson.fromJson(typedResultJson.getResultJson(),
                        type);
                itemsService.updatePackCombatPropertiesByEquipWeapon(rslt);
                msgSender.sendProcess(false);
            });
        } else if ("com.hall.items.service.ItemsService.unloadWeapon".equals(processName)) {
            tp.execute(() -> {
                Type type = new TypeToken<UnloadWeaponResult<MyWeapon, MyPlayerWeaponPack>>() {
                }.getType();
                UnloadWeaponResult<MyWeapon, MyPlayerWeaponPack> unloadWeaponResult = gson.fromJson(typedResultJson.getResultJson(),
                        type);
                itemsService.updatePackCombatValueByUnloadWeapon(unloadWeaponResult);
                msgSender.sendProcess(false);
            });
            tp.execute(() -> {
                Type type = new TypeToken<UnloadWeaponResult<MyWeapon, MyPlayerWeaponPack>>() {
                }.getType();
                UnloadWeaponResult<MyWeapon, MyPlayerWeaponPack> unloadWeaponResult = gson.fromJson(typedResultJson.getResultJson(),
                        type);
                itemsService.updatePackCombatPropertiesByUnloadWeapon(unloadWeaponResult);
                msgSender.sendProcess(false);
            });

        } else if ("com.hall.weaponenhancement.service.WeaponEnhancementService.enhanceWeapon".equals(processName)) {
            tp.execute(() -> {
                Type type = new TypeToken<TripletProcessResult<MyWeaponLevel, MyWeaponProperties, TransferResult<GoldAccount>>>() {
                }.getType();
                TripletProcessResult<MyWeaponLevel, MyWeaponProperties, TransferResult<GoldAccount>> enhanceWeaponResult = gson.fromJson(typedResultJson.getResultJson(),
                        type);
                itemsService.updatePackCombatPropertiesByEnhanceWeapon(enhanceWeaponResult);
                msgSender.sendProcess(false);
            });
            tp.execute(() -> {
                Type type = new TypeToken<TripletProcessResult<MyWeaponLevel, MyWeaponProperties, TransferResult<GoldAccount>>>() {
                }.getType();
                TripletProcessResult<MyWeaponLevel, MyWeaponProperties, TransferResult<GoldAccount>> enhanceWeaponResult = gson.fromJson(typedResultJson.getResultJson(),
                        type);
                itemsService.updateWeaponCombatValueByEnhanceWeapon(enhanceWeaponResult);
                msgSender.sendProcess(false);
            });
        } else if ("com.hall.items.service.ItemsService.updatePackCombatPropertiesByEnhanceWeapon".equals(processName)) {
            MyWeaponPackCombatProperties myWeaponPackCombatProperties = gson.fromJson(typedResultJson.getResultJson(),
                    MyWeaponPackCombatProperties.class);
            itemsService.updateAllWeaponsCombatValueByEnhanceWeapon(myWeaponPackCombatProperties);
            msgSender.sendProcess(false);
        } else if ("com.hall.items.service.ItemsService.updateWeaponCombatValue".equals(processName)) {
            MyWeaponCombatValue myWeaponCombatValue = gson.fromJson(typedResultJson.getResultJson(),
                    MyWeaponCombatValue.class);
            itemsService.updatePackCombatValue(myWeaponCombatValue);
            msgSender.sendProcess(false);
        } else if ("com.hall.items.service.ItemsService.updatePackCombatPropertiesByEquipWeapon".equals(processName)) {
            MyWeaponPackCombatProperties myWeaponPackCombatPropertie = gson.fromJson(typedResultJson.getResultJson(),
                    MyWeaponPackCombatProperties.class);
            itemsService.updateAllWeaponsCombatValueByEquipWeapon(myWeaponPackCombatPropertie);
            msgSender.sendProcess(false);
        } else if ("com.hall.items.service.ItemsService.updatePackCombatPropertiesByUnloadWeapon".equals(processName)) {
            MyWeaponPackCombatProperties myWeaponPackCombatProperties = gson.fromJson(typedResultJson.getResultJson(),
                    MyWeaponPackCombatProperties.class);
            itemsService.updateAllWeaponsCombatValueByUnloadWeapon(myWeaponPackCombatProperties);
            msgSender.sendProcess(false);
        } else if ("com.hall.items.service.ItemsService.createWeaponAndEquip".equals(processName)) {
            MyPlayerWeaponPack pack = gson.fromJson(typedResultJson.getResultJson(),
                    MyPlayerWeaponPack.class);
            itemsService.updatePackCombatPropertiesByCreateWeaponAndEquip(pack);
            msgSender.sendProcess(false);
        }
    }

    @KafkaListener(id = "hall1", topics = "process")
    public void listenViewCache(String in) {
        myViewCachedUpdater.updateByProcessJson(in);
    }

}
